package com.huike.business.service.impl;

import com.huike.business.domain.TbBusiness;
import com.huike.business.domain.TbBusinessTrackRecord;
import com.huike.business.mapper.TbBusinessMapper;
import com.huike.business.mapper.TbBusinessTrackRecordMapper;
import com.huike.business.service.TbBusinessService;
import com.huike.clues.domain.TbAssignRecord;
import com.huike.clues.domain.TbClue;
import com.huike.clues.domain.TbRulePool;
import com.huike.clues.domain.vo.AssignmentVo;
import com.huike.clues.mapper.SysUserMapper;
import com.huike.clues.mapper.TbAssignRecordMapper;
import com.huike.clues.mapper.TbClueMapper;
import com.huike.clues.mapper.TbRulePoolMapper;
import com.huike.clues.utils.HuiKeCrmDateUtils;
import com.huike.clues.utils.JobUtils;
import com.huike.common.constant.Constants;
import com.huike.common.core.domain.entity.SysUser;
import com.huike.common.exception.CustomException;
import com.huike.common.utils.DateUtils;
import com.huike.common.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: wwq
 * @Date: 2023/07/12/15:26
 * @Description:
 */
@Service
public class TbBusinessServiceImpl implements TbBusinessService {
    @Resource
    private TbBusinessMapper tbBusinessMapper;
    @Resource
    private TbAssignRecordMapper tbAssignRecordMapper;
    @Resource
    private TbRulePoolMapper tbRulePoolMapper;
    @Resource
    private TbBusinessTrackRecordMapper tbBusinessTrackRecordMapper;
    @Resource
    private TbClueMapper tbClueMapper;
    @Resource
    private SysUserMapper sysUserMapper;

    /**
     * 新增商机
     *
     * @param tbBusiness
     */
    @Override
    @Transactional
    public int add(TbBusiness tbBusiness) {
        tbBusiness.setCreateBy(SecurityUtils.getUsername());
        Date now = DateUtils.getNowDate();
        tbBusiness.setCreateTime(now);
        tbBusinessMapper.add(tbBusiness);
        TbAssignRecord tbBusinessAssignRecord = new TbAssignRecord();
        tbBusinessAssignRecord.setAssignId(tbBusiness.getId());
        tbBusinessAssignRecord.setUserId(SecurityUtils.getUserId());
        tbBusinessAssignRecord.setUserName(SecurityUtils.getUsername());
        tbBusinessAssignRecord.setDeptId(SecurityUtils.getDeptId());
        tbBusinessAssignRecord.setCreateBy(SecurityUtils.getUsername());
        tbBusinessAssignRecord.setCreateTime(now);
        tbBusinessAssignRecord.setType(Constants.rule_type_business);
        int rows = tbAssignRecordMapper.add(tbBusinessAssignRecord);

        return rows;
    }

    /**
     * 查询商机列表
     *
     * @param tbBusiness
     * @return
     */
    @Override
    public List<TbBusiness> list(TbBusiness tbBusiness) {
        List<TbBusiness> businessList = tbBusinessMapper.list(tbBusiness);
        return businessList;
    }

    /**
     * 修改商机
     *
     * @param tbBusiness
     * @return
     */
    @Override
    public int update(TbBusiness tbBusiness) {
        int rows = tbBusinessMapper.update(tbBusiness);
        return rows;
    }

    /**
     * 商机分配
     *
     * @param assignmentVo
     * @return
     */
    @Override
    @Transactional
    public String assignment(AssignmentVo assignmentVo) {
        // 查询商机规则
        TbRulePool tbRulePool = tbRulePoolMapper.getRule("1");
        Long maxNunmber = tbRulePool.getMaxNunmber();
        if (assignmentVo.getIds().length > maxNunmber) {
            return "保有量达到上限，最多选择" + maxNunmber + "条商机";
        }
        List<TbBusiness> tbBusinessList = tbBusinessMapper.getByIds(assignmentVo.getIds());
        for (TbBusiness tbBusiness : tbBusinessList) {
            // 封装插入商机跟进记录表
            TbBusinessTrackRecord tbBusinessTrackRecord = TbBusinessTrackRecord.builder()
                    .businessId(tbBusiness.getId())
                    .nextTime(tbBusiness.getNextTime())
                    .build();
            int trackRows = tbBusinessTrackRecordMapper.add(tbBusinessTrackRecord);

            // 封装插入分配记录表
            TbAssignRecord tbAssignRecord = TbAssignRecord.builder()
                    .assignId(tbBusiness.getId())
                    .type(TbAssignRecord.RecordType.BUSNIESS.getValue())
                    .userId(SecurityUtils.getUserId())
                    .userName(SecurityUtils.getUsername())
                    .latest("1")
                    .deptId(SecurityUtils.getDeptId())
                    .build();
            int assignRows = tbAssignRecordMapper.add(tbAssignRecord);

            // 修改商机状态为进行中2
            TbBusiness updateTbBusiness =new TbBusiness();
            updateTbBusiness.setId(tbBusiness.getId());
            updateTbBusiness.setStatus(TbClue.StatusType.FOLLOWING.getValue());
            int updateRows = tbBusinessMapper.update(updateTbBusiness);
        }

        return "分配成功，已为" + assignmentVo.getUserId() + "分配了" + assignmentVo.getIds().length + "条商机";
    }

    /**
     * 线索转商机
     *
     * @param clueId 线索ID
     * @return 影响行数
     */
    @Override
    public int changeBusiness(Long clueId) {
        TbClue clue = tbClueMapper.getById(clueId);
        // 更新状态为转商机
        tbClueMapper.updateNextTimeAndStatus(clueId, TbClue.StatusType.TOBUSINESS.getValue());

        TbBusiness business = new TbBusiness();
        BeanUtils.copyProperties(clue, business);
        business.setStatus(TbClue.StatusType.UNFOLLOWED.getValue());
        business.setClueId(clueId);
        business.setNextTime(null);
        tbBusinessMapper.add(business);

        // 统一由Admin分配
        SysUser admin = sysUserMapper.selectUserByUserName("admin");
        TbAssignRecord assignRecord = new TbAssignRecord();
        assignRecord.setAssignId(clue.getId());
        assignRecord.setUserId(admin.getUserId());
        assignRecord.setUserName(admin.getUserName());
        assignRecord.setDeptId(admin.getDeptId());
        return tbAssignRecordMapper.insert(assignRecord);
    }

    /**
     * 踢回公海
     *
     * @param id
     * @param reason
     * @return
     */
    @Override
    public int back(Long id, String reason) {
        TbBusiness tbBusiness = new TbBusiness();
        tbBusiness.setId(id);
        tbBusiness.setReasons(reason);
        tbBusiness.setStatus(TbClue.StatusType.FALSE.getValue());
        int rows = tbBusinessMapper.update(tbBusiness);
        return rows;
    }

    /**
     * 批量捞取
     *
     * @param assignmentVo
     * @return
     */
    @Override
    public String gain(AssignmentVo assignmentVo) {
        Long[] ids = assignmentVo.getIds();
        Long userId = assignmentVo.getUserId();
        TbRulePool rulePool = tbRulePoolMapper.getRule(Constants.rule_type_business);
        boolean isBatch = ids.length > 1;
        int assignRecords = tbAssignRecordMapper.countAssignBusinessByUser(userId);
        if (assignRecords >= rulePool.getMaxNunmber()) {
            throw new CustomException("捞取失败！最大保有量(" + rulePool.getMaxNunmber() + ")，剩余可以捞取" + (rulePool.getMaxNunmber() - assignRecords) + "条线索");
        }

        for (int i = 0; i < ids.length; i++) {
            Long businessId = ids[i];
            if (assignRecords + i > rulePool.getMaxNunmber()) {
                throw new CustomException("捞取失败！保有量达到上限，最多选择" + (rulePool.getMaxNunmber() - assignRecords) + "条线索");
            }
            TbAssignRecord assignRecord = tbAssignRecordMapper.getByAssignId(businessId, TbAssignRecord.RecordType.BUSNIESS.getValue());
            if (assignRecord != null && Objects.equals(assignRecord.getUserId(), userId)) {
                Date repeatGetTime = JobUtils.getDate(rulePool.getRepeatGetTime().intValue(), rulePool.getRepeatType(), assignRecord.getCreateTime());
                if (DateUtils.getNowDate().before(repeatGetTime)) {
                    if (isBatch) {
                        continue;
                    } else {
                        throw new CustomException("捞取失败！需要在 " + DateUtils.dateTimeHm(repeatGetTime) + " 后捞取");
                    }
                }
            }
            tbBusinessMapper.updateNextTimeAndStatus(businessId, TbClue.StatusType.UNFOLLOWED.getValue());
            TbAssignRecord tbAssignRecord = addNewRecord(businessId, userId);
            Date endDate = HuiKeCrmDateUtils.getEndDateByRule(tbAssignRecord);
            tbBusinessMapper.updateClueEndTimeById(endDate, businessId);
        }
        return "全部捞取成功";
    }

    /**
     * 查询公海池
     *
     * @param tbBusiness
     * @return
     */
    @Override
    public List<TbBusiness> pool(TbBusiness tbBusiness) {
        List<TbBusiness> businessList=tbBusinessMapper.pool(tbBusiness);
        return businessList;
    }

    private TbAssignRecord addNewRecord(Long businessId, Long userId) {
        tbAssignRecordMapper.updateLatest(businessId, TbAssignRecord.RecordType.BUSNIESS.getValue());

        TbAssignRecord assignRecord = new TbAssignRecord();
        assignRecord.setAssignId(businessId);
        assignRecord.setUserId(userId);
        assignRecord.setUserName(SecurityUtils.getUsername());
        assignRecord.setDeptId(SecurityUtils.getDeptId());
        assignRecord.setType(TbAssignRecord.RecordType.BUSNIESS.getValue());
        tbAssignRecordMapper.insert(assignRecord);
        return assignRecord;
    }
}
